home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
ldb.zip
/
LDB.DOC
< prev
next >
Wrap
Text File
|
1991-10-21
|
19KB
|
372 lines
Dear C++ Programmer,
Thank you for downloading the Loose Data Binder (LDB). The LDB is
a generic persistent container class that is less filling (smaller
code sizes and faster execution) and less stuffy (no towering
convoluted hierarchies) than other conventional container class
libraries found packaged with C++ compilers and application
framework tools.
The LDB is offered to you as shareware, meaning try before you buy.
For other than evaluation purposes directed at reaching a buy or
no buy decision, you are required by law to register the LDB. A
hard copy manual will be sent to users upon receiving registration.
The source code is also provided on either 3.5" or 5 1/4" DOS
diskette (please specify). The source is broken down into many
files along with a makefile for library building. PSW reserves
the right to withdraw this offer at any time.
LDB v1.4 $30 in U.S. $40 elsewhere
Please make checks payable to:
PSW / Power SoftWare
P.O. Box 10072
McLean, VA 22102 8072 USA
If you have questions about the LDB you can contact me at:
John Small
Voice: (703) 759-3838
CIS: 73757,2233
Exec PC: MSMALL
I have included tutorial chapter from the manual to get you
started along with seven demos.
Chapter 3
Tutorial
Copy binder.hpp, sbinder.hpp, sdata.hpp, and cbinder.hpp to your
compiler's standard header directory and the *.cpp files to your
source code directory if you have not already done so. Refer to
the header file listings in the appendix for a quick reference to
the various member functions of the LDB. If a member function's
operation is unclear, look up its entry in the reference chapter
for an explanation. Be sure to study the code of these examples,
then compile (don't forget to link to binder.obj, sbinder.obj,
sdata.obj and/or cbinder.obj as appropriate) and run them to see
the results. Are the results what you expected? Okay let's begin.
BDRDEM1.CPP
This first example is a demo of the two Binder class constructors
used in various configurations. Find their declarations in
binder.hpp or the reference chapter and make a mental note of their
parameters and defaults! I will only highlight some of their uses
here.
Okay let's walk through the code of this first example which can of
course be found in bdrdem1.cpp. Starting in main() the first
Binder, B1, is defined and constructed with all default parameters.
As you can see from binder.hpp, the binder is constructed with
flags = BDR_NO_FREE, maxNodes = BDR_MAXNODES, limit = BDR_LIMIT,
and delta = BDR_DELTA. Don't worry about this stuff for now. All
we have here is a very basic binder behaving as an elastic array of
void pointers which you supply.
(see bdrdem1.cpp) omitted here to reduce download size
The for loop inserts the char pointers of the vector V into the
rear of the binder treating it as if it were a queue. The loop is
terminated when the NULL pointer of V is attempted to be inserted
into the binder queue. The insQ() primitive always returns the
pointer it inserts into the binder and of course it's not going to
ever insert the NULL pointer so voiD0, the NULL void pointer is
returned to indicate failure!
Every binder can be treated as a list by internalizing the concept
of some node being the current node. When a binder is first
created no node is current. The stack, queue, deque, and array
primitives don't affect the current node index, after all it is a
list concept! Instead the primitives ins(), del(), insSort(),
next(), and prev(), etc. are the list primitives and they do affect
the current node pointer. The next() primitive advances the
current index and returns the void pointer to that new current node
if there is one. I'm treating the returned pointer from next() in
the example as a boolean value to test when I reach the end of the
list. One of the beauties (and pains) of C++ is that of overloaded
operators. The implicit type cast operator voiD simply returns the
pointer to the current node. You will soon notice that I have a
habit of capitalizing the last letter of type names to indicate a
pointer to that type. Here voiD means a pointer to void.
Okay, enough hand holding, it's time to speed up! The next binder,
B2, is constructed so that it is limited to a maximum of 3 nodes.
Upon destruction of the binder all nodes will be deleted which is
indicated by setting the flags parameter to BDR_OK_FREE. The
default parameter is BDR_NO_FREE which mean that nodes are simply
released when the binder is destructed. Furthermore the functions
that attempt to delete nodes are inhibited, e.g. atFree().
Notice the forEach() iterator and how it applies the block
parameter to each element in the binder in sequential order. Block
is SmallTalk terminology for a function passed as a parameter
(C/C++ programmers say function pointers).
The last binder of this example, B3, demonstrates the other
constructor which takes a vector (array) of pointers and explodes
them into a binder. By explode, I mean each cell of the vector
becomes a node in the binder. Of course the original vector is
left intact. You can implode a binder back into a dynamically
allocated vector which is returned by the vector() primitive. The
overloaded ++ operator simply applies the next() primitive to the
binder. Find the definition of operator++() in binder.hpp.
BDRDEM2.CPP
In this second example, you will see several of the various stack,
queue, list, array, and sort primitives in action. This is only a
sampling, see the class declaration of Binder in binder.hpp for a
complete listing of primitives. If you grasp the basic structure
and operation of the binder here you can fill in the details from
reading the header file.
(see bdrdem2.cpp) omitted here to reduce download size
With the first binder, B, of this example we see the primitive
atIns() used. A binder's cells are indexed from 0 to n - 1 just
like a conventional C array of n cells. AtIns() is not a list
primitive, per say, and thus doesn't affect the binder's current
node index. When no node is current, the current node number is
internally set to "nodes", one position pass the last element in
the binder. Primitives that search for a node returning its index
will return BDR_NOTFOUND to indicate no node found. What may seem
strange to you at first is that BDR_NOTFOUND is a large positive
integer, the largest number of nodes that can ever be stored in a
binder in fact. Remember that one less than this number will be
the last element's index in a completely filled binder.
The second binder, B2, is filled with a sorted list of the nodes
from binder B. Now both B and B2 contain pointers to the same
nodes! This could be a potentially hazardous situation but since
both binders don't delete their nodes upon destruction (flags =
BDR_NO_FREE in constructor) nothing is accidently deleted twice
or even once since nothing was allocated to begin with.
SBDRDEM1.CPP
SBinder, derived from Binder and Streamable, is streamable or
persistent in OOP's parlance. In other words, an SBinder can be
saved on a stream and reloaded later. Streamable nodes have
provisions for recording double ownerships and automatically
safeguarding against accidental double deletions at the same time
as providing streamability as we will see in this example.
A class must include the STREAMABLE macro in its public section and
be derived either publicly or privately from Streamable but never
virtually or otherwise multiply inherited in order for it to be
"streamable" (see StreamableInt below). If Streamable were allowed
to be a virtual base class its pointer couldn't be type casted to
its derived classes when reloading. All that is known at reload
time is that it's Streamable and you get back a Streamable class
instance pointer. The ID() member function must then be called to
find out what